//
//  SimpleMapViewViewController.m
//  SimpleMapView
//
//  Created by Stefan Ivanov on 10/11/11.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//
//  Defaulft location is set to the SuperC building of RWTH.
//  As reference material I used videos from the iPhone programming lecture
//  that I watched during my summer break. Most importantly 10 Location and Maps.
//  The solution is using MapKit to get GoogleMaps map data and CoreLocation.
//  Both frameworks are supported in XCode for purposes like what is required by the asignment.

#import "SimpleMapViewViewController.h"

@implementation SimpleMapViewViewController

@synthesize mapView;
@synthesize locManager; 
@synthesize heading;
@synthesize currentLocation;
@synthesize bar;
@synthesize appDelegate;
@synthesize redView;
@synthesize isFirstLocationUpdate;

- (void)viewDidLoad
{
    [super viewDidLoad];
    //create and initialize location manager if it's not already done
    if (!self.locManager) {
        //save it in the property
        locManager = [[CLLocationManager alloc] init];
        locManager.delegate = self;
    }
    
    //start location services setting distance filter to whenever user moves and navigation accuracy
    locManager.distanceFilter = kCLDistanceFilterNone;
    locManager.desiredAccuracy = kCLLocationAccuracyBest;
    [locManager startUpdatingLocation];
    
    //start heading services setting heading filter in similar fashion as above
    if ([CLLocationManager headingAvailable]) {
        locManager.headingFilter = kCLHeadingFilterNone;
        [locManager startUpdatingHeading];
    }
    
    
    //disable panning in the mapview so it's always centered to oneself
    [mapView setScrollEnabled:YES];
    
    //make mapview show the user's location and the visual style to be standard
    mapView.showsUserLocation = YES;
    self.mapView.mapType = MKMapTypeStandard;
    
    //set the mapview delegate to self for the MKAnnotation callbacks to get called
    [mapView setDelegate:(id)self];
    
    //create the bar, place it top of the screen and add it to the veiw
    bar = [[BarView alloc] initWithFrame:CGRectMake(mapView.frame.origin.x , mapView.frame.origin.y, mapView.frame.size.width, 50)];
    [self.view addSubview:bar];
    
    //set the app delegate where the current amount of points is stored
    appDelegate = (SimpleMapViewAppDelegate *)[[UIApplication sharedApplication] delegate];

}
- (void)dealloc
{
    [mapView release];
    [locManager release];
    [currentLocation release];
    [bar release];
    [appDelegate release];
    [super dealloc];
}

- (void)didReceiveMemoryWarning
{
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
    
    // Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle

/*
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
    [super viewDidLoad];
}
*/
- (void)viewDidAppear:(BOOL)animated
{
    
    //if the view has just appeared then we set isFirstLocationUpdate variable
    isFirstLocationUpdate = YES;
}

-(void)viewDidDisappear:(BOOL)animated
{
    
    //if the view has disappeared then we set isFirstLocationUpdate variable
    isFirstLocationUpdate = NO;
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
    self.mapView = nil;

}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
    if (![newLocation isEqual:oldLocation]) {
        //update the location
        currentLocation = newLocation;
        
        if (isFirstLocationUpdate) {
            //center the mapview on the current location of the player and zoom to particular level 
            [self.mapView setRegion:MKCoordinateRegionMake(currentLocation.coordinate, MKCoordinateSpanMake(0.005, 0.005 )) animated:YES];
        }else{
            //center the mapview on the current location of the player
            [self.mapView setCenterCoordinate:self.mapView.userLocation.location.coordinate animated:YES];
        }
        
        //check if a checkpoint is within 10m from current location
        CheckPoint *cp = [[[CheckPoint alloc]init] autorelease];
        for (cp in appDelegate.availableCheckpoints) {
            CLLocation *cpLoc = [[[CLLocation alloc] initWithLatitude:cp.coordinate.latitude longitude:cp.coordinate.longitude] autorelease];
            if ([cpLoc distanceFromLocation:currentLocation] <= 10.0) {
                //add points to current amount using a fade in - fade out animation
                [UIView animateWithDuration:1.0
                                 animations:^{ 
                                     //hide label to change its value
                                     bar.pointAmount.alpha = 0.0;
                                 } 
                                 completion:^(BOOL finished){
                                     
                                     [UIView animateWithDuration:1.0
                                                      animations:^{ 
                                                          //add the aquired points to the current amount
                                                          appDelegate.currentPoints += [cp.points intValue];
                                                          
                                                          //make visile again
                                                          bar.pointAmount.alpha = 1.0;
                                                      } 
                                                      completion:^(BOOL finished){
                                                          ;
                                                      }];
                                     
                                 }];
                
                //remove checkpoint from list
                [appDelegate.availableCheckpoints removeObject:cp];
                
                //remove the pin from the mapview
                [mapView removeAnnotation:cp];
                
                //send update to server that checkpoint has been collected so that others are informed as well
                //[server send:something to:someone] (or whatever the method is)
            }
        }
        
        
        //send update to the server maybe every time maybe only when timer is trigerred
        //[server send:something to:someone] (or whatever the method is)
        
    }
}

-(void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading
{
    if (newHeading.headingAccuracy < 0)
        return;
    
    //use true heading if its value is valid
    CLLocationDirection tempHeading = ((newHeading.trueHeading >0)?newHeading.trueHeading:newHeading.magneticHeading);
    
    //update the heading
    heading = tempHeading;
    
    //set the transform of the map view to be such that it rotates according to the heading direction
    [mapView setTransform:CGAffineTransformMakeRotation(-1 * heading * 3.14159 / 180)];
    
}

- (IBAction)changePoints:(id)sender 
{
    //make animation for fading the value out updating it and fading it back in
    [UIView animateWithDuration:1.0
                     animations:^{ 
                         //hide label to change its value
                         bar.pointAmount.alpha = 0.0;
                     } 
                     completion:^(BOOL finished){
                         
                         [UIView animateWithDuration:1.0
                                          animations:^{ 
                                              //add the aquired points to the current amount
                                              appDelegate.currentPoints += 300;
                                              
                                              //make visile again
                                              bar.pointAmount.alpha = 1.0;
                                          } 
                                          completion:^(BOOL finished){
                                              ;
                                          }];
                         
                     }];
}

- (IBAction)huntedDown:(id)sender 
{
    //create the red view
    redView = [[UIView alloc] init];
    
    //set its color, opacity and frame
    [redView setBackgroundColor:[UIColor redColor]];
    [redView setAlpha:0.0];
    [redView setFrame:CGRectMake(mapView.frame.origin.x , mapView.frame.origin.y + 50, mapView.frame.size.width, mapView.frame.size.height - 50)];
    
    //add it as a subview to the mapview by putting it just above it
    [self.view insertSubview:redView aboveSubview:self.view];
    
    
    //get the path of the alarm sound
    NSString *path = [NSString stringWithFormat:@"%a%a", [[NSBundle mainBundle]resourcePath], @"/beep.wav"];
    SystemSoundID soundID;
    
    //get url from the path
    NSURL *filePath = [NSURL fileURLWithPath:path isDirectory:NO];
    
    //create the sound using audio services
    AudioServicesCreateSystemSoundID((CFURLRef)filePath, &soundID);
    
    
    //make animation that repeats and autoreverses
    [UIView animateWithDuration:1.0
                          delay:0.0
                        options:UIViewAnimationOptionRepeat|UIViewAnimationOptionAutoreverse
                     animations:^{ 
                         //play the alert sound
                         AudioServicesPlaySystemSound(soundID);
                         
                         //hide label to change its value
                         [redView setAlpha:0.4];
                     } 
                     completion:^(BOOL finished){
                         ;
                     }];
}
//at later stage this will be called when checkpoints are received from the server
- (IBAction)placePins:(id)sender {
    CheckPoint *cp = [[CheckPoint alloc]init];
    for (cp in appDelegate.availableCheckpoints) {
        [mapView addAnnotation:cp];
    }
    
}

- (MKAnnotationView *)mapView:(MKMapView *)map viewForAnnotation:(id <MKAnnotation>)annotation {
    
    MKPinAnnotationView *annotationView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:@"myAnnotationID"];
    
    if (annotationView == nil) {
        annotationView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"myAnnotationID"] autorelease];
        
        annotationView.canShowCallout = YES;
    }
    if ([annotation isKindOfClass:[MKUserLocation class]]) {
        [annotationView setImage:[UIImage imageNamed:@"playa.png"]];
    }else{    
        [annotationView setImage:[UIImage imageNamed:@"shrine.png"]];
    }
    return annotationView;
}

@end
